package com.zbkj.front.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * NettyServer
 * </p>
 *
 * @author ywy
 * @since 2021-08-05
 */
@Slf4j
public class NettyServer {

    /**
     * 线程池组
     */
    public EventLoopGroup work;

    /**
     * 线程池组
     */
    public EventLoopGroup boss;

    /**
     * 端口
     */
    private Integer port = 19090;

    /**
     * url
     */
    private String path = "/ws";

    public NettyServer() {
    }

    public NettyServer(Integer port, String path) {
        this.port = port;
        this.path = path;
    }


    public void start() throws InterruptedException {
        log.info("netty starting......{},{}", port, path);
        //线程池组
        work = new NioEventLoopGroup();
        boss = new NioEventLoopGroup();
        //
        ServerBootstrap bootstrap = new ServerBootstrap()
                .group(work, boss)
                .channel(NioServerSocketChannel.class)
                .localAddress(port)
                //全连接队列数,并不代表只能1024个连接。accept()事件处理不了才堆积在队列
                .option(ChannelOption.SO_BACKLOG, 1024)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        //配置链式解码器
                        ChannelPipeline pipeline = ch.pipeline();
                        //解码成HttpRequest
                        pipeline.addLast(new HttpServerCodec());
                        //块写入写出内容Handler
                        pipeline.addLast(new ChunkedWriteHandler());
                        //解码成FullHttpRequest
                        pipeline.addLast(new HttpObjectAggregator(1024 * 64 * 64));
                        //添加WebSocket解编码
                        pipeline.addLast(new WebSocketServerProtocolHandler(path));
                        //空闲读、写处理器 ---> userEventTriggered方法
                        pipeline.addLast(new IdleStateHandler(1800, 1800, 1800, TimeUnit.SECONDS));
                        //添加处自定义的处理器
                        pipeline.addLast(new YgxHandler());
                    }
                });
        //启动服务 绑定端口
        ChannelFuture channelFuture = bootstrap.bind().sync();
        //对关闭通道进行监听
        channelFuture.channel().closeFuture().sync();
    }


    /**
     * 释放资源
     *
     * @throws InterruptedException
     */
    public void destroy() throws InterruptedException {
        if (work != null) {
            work.shutdownGracefully().sync();
        }
        if (boss != null) {
            boss.shutdownGracefully().sync();
        }
        //清空存放用户id与管道Channel关系的map
        //UserIdChannelMap.userIdChannelMap.clear();
        //清空排队队列
//        MembersAreaQueue.getInstance().delete();
//        NonMembersAreaQueue.getInstance().delete();
//        ExperienceAreaQueue.getInstance().delete();
        log.info("netty shut down......");
    }


}
